﻿using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

public class UGUIPointEventTrigger : MonoBehaviour,
    IPointerClickHandler,
    IPointerEnterHandler,
    IPointerExitHandler,
    IPointerDownHandler,
    IPointerUpHandler
{
    // Callbacks for different pointer events
    private UnityAction<PointerEventData> onPointerClickCallback;
    private UnityAction<PointerEventData> onPointerEnterCallback;
    private UnityAction<PointerEventData> onPointerExitCallback;
    private UnityAction<PointerEventData> onPointerDownCallback;
    private UnityAction<PointerEventData> onPointerUpCallback;

    private UnityAction onPointerLongPressCallback;   //当长按

    public float durationThreshold = 0.3f;
    private bool isPointerDown = false;
    private bool longPressTriggered = false;
    private float timePressStarted;
    public float ClickInterval = 0;
    private float clickIntervalTimer = 0;
    void Update()
    {
        if (isPointerDown && !longPressTriggered && onPointerLongPressCallback != null)
        {
            if (Time.unscaledTime - timePressStarted > durationThreshold)
            {
                longPressTriggered = true;
                onPointerLongPressCallback.Invoke();
            }
        }

        if (clickIntervalTimer > 0)
        {
            clickIntervalTimer -= Time.deltaTime;
        }
    }

    /// <summary>
    /// Adds a callback for the Pointer Click event.
    /// </summary>
    public static void AddPointerClick(GameObject gameObject, UnityAction<PointerEventData> callback,float clickInterval = 0)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerClickCallback += callback;
        trigger.ClickInterval = clickInterval;
    }

    /// <summary>
    /// Adds a callback for the Pointer Enter event.
    /// </summary>
    public static void AddPointerEnter(GameObject gameObject, UnityAction<PointerEventData> callback)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerEnterCallback += callback;
    }

    /// <summary>
    /// Adds a callback for the Pointer Exit event.
    /// </summary>
    public static void AddPointerExit(GameObject gameObject, UnityAction<PointerEventData> callback)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerExitCallback += callback;
    }

    /// <summary>
    /// Adds a callback for the Pointer Down event.
    /// </summary>
    public static void AddPointerDown(GameObject gameObject, UnityAction<PointerEventData> callback)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerDownCallback += callback;
    }

    /// <summary>
    /// Adds a callback for the Pointer Up event.
    /// </summary>
    public static void AddPointerUp(GameObject gameObject, UnityAction<PointerEventData> callback)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerUpCallback += callback;
    }

    /// <summary>
    /// Adds a callback for the Pointer Up event.
    /// </summary>
    public static void AddPointerLongPress(GameObject gameObject, UnityAction callback)
    {
        var trigger = gameObject.GetComponent<UGUIPointEventTrigger>() ?? gameObject.AddComponent<UGUIPointEventTrigger>();
        trigger.onPointerLongPressCallback += callback;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        //触发长按，就不触发点击
        if (longPressTriggered) { return; }
        if (clickIntervalTimer > 0) 
        {
            return;
        }
        clickIntervalTimer = ClickInterval;
        onPointerClickCallback?.Invoke(eventData);
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        onPointerEnterCallback?.Invoke(eventData);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        onPointerExitCallback?.Invoke(eventData);
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        isPointerDown = true;
        longPressTriggered = false;
        timePressStarted = Time.unscaledTime;
        onPointerDownCallback?.Invoke(eventData);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isPointerDown = false;
        onPointerUpCallback?.Invoke(eventData);
    }
    
}
